﻿using RayDen.Library.Core.Primitives;
using RayDen.RayEngine;
using RayDen.RayEngine.Core.Devices;
using RayDen.RayEngine.Core.Types;
using RayDen.RayEngine.Data;
using RayDen.RayEngine.VertexFramework;

namespace PathEngine
{
    public interface IRayTracingDevice
    {
        void SetData(AccellerationData data);
        void TraceBuffer(RayCollection rayBuffer);
    }

    public class CpuRayTracingDevice : WorkingQueueDevice<RayCollection>, IRayTracingDevice
    {
        private AccellerationData data;

        protected override void Process(RayCollection data)
        {
            this.TraceBuffer(data);
        }

        public void SetData(AccellerationData data)
        {
            this.data = data;
        }

        public void TraceBuffer(RayCollection rayBuffer)
        {
            throw new System.NotImplementedException();
        }
    }

    public struct PathVertexData
    {
        public Point HitPoint;
        public Point DpDu, DpDv;
        public Normal GeoNormal, ShadingNormal;
        public Normal DnDu, DnDv;
        public UV TexCoords;
    }

    public abstract class PathElement
    {
        public PathVertexData GeoData;
        public abstract PathVertexType Type { get; }
    }

    public class ObserverPathElement : PathElement
    {
        public CameraSample CameraSample;
        public override PathVertexType Type
        {
            get { return PathVertexType.Camera; }
        }
    }


    public class LightsourcePathElement : PathElement
    {
        public LightSample LightSample;
        public override PathVertexType Type
        {
            get { return PathVertexType.DiffuseLightsource; }
        }
    }

    public class GeometryPathElement : PathElement
    {
        public BsdfSample BsdfSample;

        public override PathVertexType Type
        {
            get { return BsdfSample.Bounce.HasFlag(BxDFType.Diffuse) ?
                                    PathVertexType.DiffuseGeometry : 
                                    BsdfSample.Bounce.HasFlag(BxDFType.Specular) || BsdfSample.Bounce.HasFlag(BxDFType.Diffuse) ? 
                                        PathVertexType.SpecularGeometry : PathVertexType.Geometry; 
            }
        }
    }

    public class PathSampler
    {
        private PathElement[] pathVertices;

        public PathSampler(Sample sample, int max)
        {
            pathVertices = new PathElement[max];
        }
    }
}